// Copyright (c) 2012-2013, yuno. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
//    this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of contributors
//    may be used to endorse or promote products derived from this software
//    without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
package sugarmintcandy.widgetwindow;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.ContentObserver;
import android.os.Bundle;
import android.os.Handler;
import android.os.Parcelable;
import android.preference.PreferenceManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class OpenWindowActivity extends Activity implements
	SharedPreferences.OnSharedPreferenceChangeListener {
    private MainApplication mApplication;
    private MainDatabase mDatabase;
    private MyAppWidgetHostManager mHostManager;
    private SharedPreferences mPreferences;
    private MyAdapter mAdapter;
    private MyContentObserver mContentObserver;
    private int mAddingAppWidgetId;
    private int mCurrentWorkspace;

    @SuppressWarnings("deprecation")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	mApplication = (MainApplication) getApplication();
	mDatabase = mApplication.getDatabase();
	mHostManager = mApplication.getHostManager();
	mContentObserver = new MyContentObserver(new Handler());
	mDatabase.registerObserver(mContentObserver);
	mPreferences = PreferenceManager.getDefaultSharedPreferences(this);
	mPreferences.registerOnSharedPreferenceChangeListener(this);
	mCurrentWorkspace = mPreferences.getInt(
		PreferenceKeys.CURRENT_WORKSPACE, 0);
	mAdapter = new MyAdapter();
	showDialog(R.id.open_window);
    }

    @Override
    protected void onDestroy() {
	super.onDestroy();
	mDatabase.unregisterObserver(mContentObserver);
	mPreferences.unregisterOnSharedPreferenceChangeListener(this);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
	super.onRestoreInstanceState(savedInstanceState);
	mAddingAppWidgetId = savedInstanceState.getInt("mAddingAppWidgetId");
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
	super.onSaveInstanceState(outState);
	outState.putInt("mAddingAppWidgetId", mAddingAppWidgetId);
    }

    @Deprecated
    @Override
    protected Dialog onCreateDialog(int id) {
	if (id == R.id.open_window) {
	    AlertDialog.Builder b = new AlertDialog.Builder(this);
	    b.setCancelable(true);
	    b.setOnCancelListener(new DialogInterface.OnCancelListener() {
		@Override
		public void onCancel(DialogInterface dialog) {
		    finish();
		}
	    });
	    b.setAdapter(mAdapter, new DialogInterface.OnClickListener() {
		@Override
		public void onClick(DialogInterface dialog, int which) {
		    WindowInfo info = mAdapter.getItem(which);
		    if (info == null) {
			doNewWindow();
		    } else {
			mDatabase.fetchWindowInfo(info);
			info.workspace |= 1 << mCurrentWorkspace;
			mDatabase.updateWindowInfo(info, true);
			finish();
		    }
		}
	    });
	    AlertDialog d = b.create();
	    d.getWindow().setWindowAnimations(android.R.style.Animation_Dialog);
	    return d;
	}
	if (id == R.id.configure_error) {
	    AlertDialog.Builder b = new AlertDialog.Builder(this);
	    b.setCancelable(true);
	    b.setIcon(android.R.drawable.ic_dialog_alert);
	    b.setTitle(R.string.error_title);
	    b.setMessage(R.string.configure_error);
	    b.setOnCancelListener(new DialogInterface.OnCancelListener() {
		@Override
		public void onCancel(DialogInterface dialog) {
		    finish();
		}
	    });
	    b.setPositiveButton(android.R.string.ok,
		    new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
			    finish();
			}
		    });
	    return b.create();
	}
	return super.onCreateDialog(id);
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
	    String key) {
	if (PreferenceKeys.CURRENT_WORKSPACE.equals(key)) {
	    mCurrentWorkspace = mPreferences.getInt(
		    PreferenceKeys.CURRENT_WORKSPACE, 0);
	    mAdapter.refresh();
	}
    }

    private void doNewWindow() {
	mAddingAppWidgetId = mHostManager.allocateAppWidgetId();
	Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_PICK);
	intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAddingAppWidgetId);
	intent.putExtra(Intent.EXTRA_TITLE, getString(R.string.new_window));
	intent.putParcelableArrayListExtra(AppWidgetManager.EXTRA_CUSTOM_INFO,
		new ArrayList<Parcelable>());
	intent.putParcelableArrayListExtra(
		AppWidgetManager.EXTRA_CUSTOM_EXTRAS, new ArrayList<Bundle>());
	startActivityForResult(intent, R.id.app_widget_pick);
    }

    private void doNewWindow(int appWidgetId) {
	WindowInfo info = new WindowInfo();
	info.init(mDatabase, appWidgetId);
	mDatabase.addWindowInfo(info);
    }

    private boolean doConfigureWidget(int appWidgetId,
	    AppWidgetProviderInfo info) {
	Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
	intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
	intent.setComponent(info.configure);
	startActivityForResult(intent, R.id.app_widget_configure);
	return true;
    }

    @SuppressWarnings("deprecation")
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
	super.onActivityResult(requestCode, resultCode, data);
	if (requestCode == R.id.app_widget_pick && mAddingAppWidgetId != 0) {
	    int appWidgetId = mAddingAppWidgetId;
	    AppWidgetProviderInfo info = AppWidgetManager.getInstance(this)
		    .getAppWidgetInfo(appWidgetId);
	    if (resultCode == RESULT_OK && info != null) {
		if (info.configure != null) {
		    try {
			doConfigureWidget(appWidgetId, info);
		    } catch (RuntimeException ex) {
			mHostManager.deleteAppWidgetId(appWidgetId);
			mAddingAppWidgetId = 0;
			showDialog(R.id.configure_error);
		    }
		} else {
		    doNewWindow(appWidgetId);
		    mAddingAppWidgetId = 0;
		    finish();
		}
	    } else {
		mHostManager.deleteAppWidgetId(appWidgetId);
		mAddingAppWidgetId = 0;
		finish();
	    }
	}
	if (requestCode == R.id.app_widget_configure && mAddingAppWidgetId != 0) {
	    int appWidgetId = mAddingAppWidgetId;
	    if (resultCode == RESULT_OK) {
		doNewWindow(appWidgetId);
		mAddingAppWidgetId = 0;
	    } else {
		mHostManager.deleteAppWidgetId(appWidgetId);
		mAddingAppWidgetId = 0;
	    }
	    finish();
	}
    }

    private class MyAdapter extends BaseAdapter {
	private WindowInfo[] mInfoList;

	MyAdapter() {
	    refresh();
	}

	public void refresh() {
	    int mask = 1 << mCurrentWorkspace;
	    ArrayList<WindowInfo> list = new ArrayList<WindowInfo>();
	    WindowInfo[] infoList = mDatabase.getWindowInfoList();
	    Collections.reverse(Arrays.asList(infoList));
	    for (WindowInfo info : infoList) {
		if ((info.workspace & mask) == 0) {
		    list.add(info);
		}
	    }
	    list.add(null);
	    mInfoList = list.toArray(new WindowInfo[list.size()]);
	    notifyDataSetChanged();
	}

	@Override
	public int getCount() {
	    return mInfoList.length;
	}

	@Override
	public WindowInfo getItem(int position) {
	    return mInfoList[position];
	}

	@Override
	public long getItemId(int position) {
	    return position;
	}

	@Override
	public View getView(int position, View view, ViewGroup parent) {
	    Context context = parent.getContext();
	    if (view == null) {
		LayoutInflater inflater = LayoutInflater.from(context);
		view = inflater.inflate(R.layout.open_window_item, parent,
			false);
	    }
	    View titleBar = view.findViewById(R.id.title_bar);
	    ImageView imageView = (ImageView) view
		    .findViewById(R.id.image_view);
	    TextView text1 = (TextView) view.findViewById(android.R.id.text1);
	    WindowInfo info = getItem(position);
	    if (info == null) {
		titleBar.setBackgroundColor(0);
		imageView.setBackgroundColor(0);
		imageView.setImageDrawable(null);
		text1.setText(R.string.new_window_ellisis);
	    } else {
		titleBar.setBackgroundColor(info.titleBarColor);
		imageView.setBackgroundColor(info.windowColor);
		imageView.setImageDrawable(info.loadIcon(context));
		text1.setText(info.getTitleBarText());
	    }
	    return view;
	}
    }

    private class MyContentObserver extends ContentObserver {
	public MyContentObserver(Handler handler) {
	    super(handler);
	}

	@Override
	public void onChange(boolean selfChange) {
	    mAdapter.refresh();
	}
    }
}
